package current.cas;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicStampedReference;

public class ABADemo {

    static AtomicReference<Integer> atomicReference = new AtomicReference<>(100);
    static AtomicStampedReference<Integer> atomicStampedReference = new AtomicStampedReference<>(100,1);
    public static void main(String[] args) {

            /*new Thread(() -> {
                    //线程要执行的代码
                System.out.println(Thread.currentThread().getName() + atomicReference.compareAndSet(100, 200) + "value :" + atomicReference.get());
                System.out.println(Thread.currentThread().getName() + atomicReference.compareAndSet(200, 100) + "value :" + atomicReference.get());
            },"t1").start();
        System.out.println("----以下是ABA问题的产生------");
        new Thread(() -> {
            //线程要执行的代码
            //暂停2秒钟，保证上面的线程完成了一次ABA操作
            try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }
            atomicReference.compareAndSet(100,300);
            System.out.println(Thread.currentThread().getName() + "atomicReference value : " + atomicReference.get());
        },"t2").start();

        try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); }*/
        System.out.println("------以下是ABA问题解决--------");

            new Thread(() -> {
                    //线程要执行的代码
                int stamp = atomicStampedReference.getStamp();
                System.out.println(Thread.currentThread().getName() +"\t 第1次版本号：" +stamp);
                //暂停1秒t3线程
                try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }

                atomicStampedReference.compareAndSet(100, 300, stamp, atomicStampedReference.getStamp() +1);
                System.out.println(Thread.currentThread().getName() +"\t 第2次版本号：" +atomicStampedReference.getStamp());
                try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }
                atomicStampedReference.compareAndSet(300, 100, atomicStampedReference.getStamp(), atomicStampedReference.getStamp() +1);
                System.out.println(Thread.currentThread().getName() +"\t 第3次版本号：" +atomicStampedReference.getStamp());

                },"t3").start();

                    new Thread(() -> {
                            //线程要执行的代码
                        int stamp = atomicStampedReference.getStamp();
                        System.out.println(Thread.currentThread().getName() +"\t 第1次版本号：" + stamp);

                        try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); }

                        boolean result = atomicStampedReference.compareAndSet(100, 2018,stamp,stamp+1);
                        int newStamp = atomicStampedReference.getStamp();

                        System.out.println("修改成功否？result = " + result);
                        System.out.println("最新版本号："+ newStamp);
                        System.out.println(Thread.currentThread().getName() + "当前实际最新值为：" + atomicStampedReference.getReference());

                         },"t4").start();
    }
}
